package coms.mianshi.staticinnerclass;

/**
 * @program: item_02
 * @description: 静态内部类
 * 假设类A有静态内部类B和非静态内部类C，创建B和C的区别为：
 * A a=new A();
 * A.B b=new A.B();
 * A.C c=a.new C();
 * @author: LL
 * @create: 2021-03-03 10:42
 */
public class OutClassTest {

    /**
     * 1 static 静态修饰符
     * 在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的。
     * static修饰表示静态的，在类加载时JVM会把它放到方法区，被本类以及本类中所有实例所公用。
     * 在编译后所分配的内存会在一直存在，直到程序退出内存才会释放这个空间。如果一个被所有实例公用的方法被申明为static，那么就可以节省空间了，不用每个实例初始化的时候都被分配到内存。
     * <p>
     * 2.内部类
     * 定义在一个类内部的类叫内部类，包含内部类的类称为外部类。内部类可以声明public、protected、private等访问限制，可以声明 为abstract的供其他内部类或外部类继承与扩展，或者声明为static、final的，也可以实现特定的接口。
     * 外部类按常规的类访问方式使用内部 类，唯一的差别是外部类可以访问内部类的所有方法与属性，包括私有方法与属性。
     * <p>
     * 3.静态类（只有内部类才能被声明为静态类，即静态内部类）
     * 1.只能在内部类中定义静态类
     * 2.静态内部类与外层类绑定，即使没有创建外层类的对象，它一样存在。
     * 3.静态类的方法可以是静态的方法也可以是非静态的方法，静态的方法可以在外层通过静态类调用，而非静态的方法必须要创建类的对象之后才能调用。
     * 5.只能引用外部类的static成员变量（也就是类变量）。
     * 6.如果一个内部类不是被定义成静态内部类，那么在定义成员变量或者成员方法的时候，是不能够被定义成静态的。
     */

    int out1 = 1;
    static int out2 = 1;

    void out() {
        System.out.println("非静态");
    }

    static void outStatic() {
        System.out.println("静态");
    }

    //内部类
    public class InnerClass {
        void InnerClass() {
            System.out.println("InnerClass!");
            System.out.println(OutClassTest.this.out1);
            System.out.println(out2);
            out();
            outStatic();//静态内部类只能够访问外部类的静态成员
        }
        // static void inner(){}  static int i=1; 非静态内部类不能有静态成员（方法、属性）
    }

    //静态内部类
    public static class InnerStaticClass {
        void InnerStaticClass() {
            System.out.println("InnerStaticClass");
            //  System.out.println(out1);out(); 静态内部类只能够访问外部类的静态成员
            System.out.println(out2);
            outStatic();
        }

        static void innerStatic() {
        }

        static int i = 1;//静态内部类能有静态成员（方法、属性）
    }


    public static void main(final String[] args) {
        final OutClassTest a = new OutClassTest();
        final OutClassTest.InnerStaticClass b = new OutClassTest.InnerStaticClass();//创建静态内部类
        final OutClassTest.InnerClass c = a.new InnerClass();//创建非静态内部类
        b.InnerStaticClass();
        c.InnerClass();
    }

}
